#include<iostream>
#include<pthread.h>
#include<string>
#include<queue>
#include<stdio.h>
#include<unistd.h>
using namespace std;
int flag =1;
template<class T>
class blockqueue
{
	public:
	blockqueue(size_t maxcap=5)
		:max_cap(maxcap)
	{
	pthread_mutex_init(&mutex,nullptr);
	pthread_cond_init(&condp,nullptr);
	pthread_cond_init(&condc,nullptr);
	};
	void push(const T& val)
	{
		pthread_mutex_lock(&mutex);
		while(_q.size()==max_cap)
			pthread_cond_wait(&condp,&mutex);
		_q.push(val);
		pthread_cond_signal(&condc);
		pthread_mutex_unlock(&mutex);

	};
	void pop(T* retval)
	{
		pthread_mutex_lock(&mutex);
		while(_q.size()==0)
			pthread_cond_wait(&condc,&mutex);
		*retval =_q.front();
		_q.pop();
		pthread_cond_signal(&condp);
		pthread_mutex_unlock(&mutex);

	};

	~blockqueue()
	{
	pthread_mutex_destroy(&mutex);
	pthread_cond_destroy(&condp);
	pthread_cond_destroy(&condc);

	};
	int getsize()
	{return _q.size();};



	private:
	queue<T> _q;
	pthread_mutex_t mutex;
	pthread_cond_t condp;
	pthread_cond_t condc;
	size_t max_cap;

};
#define task_t int//任务数据类型
void* produce(void* args)
{
	blockqueue<task_t>* bq=static_cast<blockqueue<task_t>*>(args);
	task_t tasks[5]={1,2,3,4,5};//构建数据
       for(int i =0;i<5;i++)
       {
	       
	       bq->push(tasks[i]);//生产数据
	       bq->push(tasks[i]);//生产数据

       }
       return nullptr;

};
void* consume(void* args)
{
	blockqueue<task_t>* bq=static_cast<blockqueue<task_t>*>(args);
	task_t task;
	while(1)
	{
		sleep(1);
	bq->pop(&task);//获取数据
	cout<<task<<endl;//处理数据
	cout<<"目前队列的数据个数为："<<bq->getsize()<<endl;
	};
	return nullptr;



};

int main()
{
	blockqueue<task_t>* bq=new blockqueue<task_t>();
	pthread_t p,c;
	pthread_create(&p,nullptr,produce,bq);
	pthread_create(&c,nullptr,consume,bq);
	pthread_join(p,nullptr);
	pthread_join(c,nullptr);

	return 0;

}
